// Copyright (C) joyinter
// All rights reserved.
// 
// Author : Jiang Li
// Date   : 2005-5-8

#include "stdafx.h"
#include "apihelp.h"
#include "strcrypt.h"
#include "module.h"

#ifdef _DEBUG

void JoyGuardGenCryptNames()
{
    static char origStr[][64] = 
    {
        "VirtualProtectEx",
        "OpenProcess",
        "WaitForSingleObject",
        "CreateThread",
        "kernel32.dll",
        "CreateToolhelp32Snapshot",
        "Module32First",
        "Module32Next",
        "Process32First",
        "Process32Next",
        "ReadProcessMemory",
        "WriteProcessMemory",
    };
    char cryptStrBuf[4096];
    memset(cryptStrBuf, 0, sizeof(cryptStrBuf));
    char* cryptStr = cryptStrBuf;

    int strC = sizeof(origStr)/sizeof(origStr[0]);
    for(int i = 0; i < strC; ++ i)
    {
        cryptStr += sprintf(cryptStr, "static BYTE s_%s[] = { ", origStr[i]);
        JoyGuard::StrCrypt::Encrypt(origStr[i], origStr[i]);
        char* s = origStr[i];
        for(; *s; ++ s)
        {
            cryptStr += sprintf(cryptStr, "0x%.2x,", (BYTE)(*s));
        }
        cryptStr += sprintf(cryptStr, "0x00 };\r\n");
    }
}

#endif // _DEBUG

namespace JoyGuard
{
static BYTE s_kernel32_dll[] = { 0x91,0x94,0x9a,0x8d,0xcd,0x9a,0x93,0xcc,0x93,0xd1,0x9b,0x93,0x00 };
static BYTE s_CreateToolhelp32Snapshot[] = { 0x9e,0xbc,0x8d,0x9a,0x90,0x8b,0x9a,0xab,0x9a,0x90,0x93,0x97,0xcd,0x93,0x8f,0xcc,0x8f,0xac,0x91,0x9e,0x8b,0x8c,0x97,0x90,0x00 };
static BYTE s_Module32First[] = { 0x8a,0xb2,0x90,0x9b,0xcd,0x93,0x9a,0xcc,0x8c,0xb9,0x96,0x8d,0x8b,0x00 };
static BYTE s_Module32Next[] = { 0x8a,0xb2,0x90,0x9b,0xcd,0x93,0x9a,0xcc,0x8b,0xb1,0x9a,0x87,0x00 };
static BYTE s_Process32First[] = { 0x9c,0xaf,0x8d,0x90,0xcc,0x9a,0x8c,0x8c,0x8d,0xcd,0xb9,0x96,0x8c,0x8b,0x00 };
static BYTE s_Process32Next[] = { 0x9c,0xaf,0x8d,0x90,0xcc,0x9a,0x8c,0x8c,0x87,0xcd,0xb1,0x9a,0x8b,0x00 };
static BYTE s_ReadProcessMemory[] = { 0x9b,0xad,0x9a,0x9e,0x9c,0xaf,0x8d,0x90,0xb2,0x9a,0x8c,0x8c,0x8d,0x9a,0x92,0x90,0x86,0x00 };
static BYTE s_WriteProcessMemory[] = { 0x8b,0xa8,0x8d,0x96,0x90,0x9a,0xaf,0x8d,0x8c,0x9c,0x9a,0x8c,0x90,0xb2,0x9a,0x92,0x8d,0x86,0x00 };
static BYTE s_CreateThread[] = { 0x9e,0xbc,0x8d,0x9a,0x97,0x8b,0x9a,0xab,0x9b,0x8d,0x9a,0x9e,0x00 };
static BYTE s_OpenProcess[] = { 0x91,0xb0,0x8f,0x9a,0x9c,0xaf,0x8d,0x90,0x9a,0x8c,0x8c,0x00 };
static BYTE s_WaitForSingleObject[] = { 0x8b,0xa8,0x9e,0x96,0xac,0xb9,0x90,0x8d,0x93,0x96,0x91,0x98,0x95,0x9a,0xb0,0x9d,0x9a,0x9c,0x8b,0x00 };
static BYTE s_VirtualProtectEx[] = { 0x8b,0xa9,0x96,0x8d,0xaf,0x8a,0x9e,0x93,0x9a,0x8d,0x90,0x8b,0x87,0x9c,0x8b,0xba,0x00 };

#pragma warning(disable : 4073)
#pragma init_seg(lib)

static HMODULE h_kernel = Module::GetHandle((char*)s_kernel32_dll);

// CreateToolhelp32Snapshot
//##ModelId=44C4B60E02EE
typedef HANDLE (WINAPI *PCreateToolhelp32Snapshot)(DWORD dwFlags, DWORD th32ProcessID);
static PCreateToolhelp32Snapshot fn_CreateToolhelp32Snapshot = (PCreateToolhelp32Snapshot)Module::GetProc(h_kernel, (char*)s_CreateToolhelp32Snapshot);
//##ModelId=44C4B60E0281
HANDLE ApiHelp::CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID)
{
    return fn_CreateToolhelp32Snapshot(dwFlags, th32ProcessID);
}

// Module32First
//##ModelId=44C4B60E02F0
typedef BOOL (WINAPI *PModule32First)(HANDLE hSnapshot, LPMODULEENTRY32 lpme);
static PModule32First fn_Module32First = (PModule32First)Module::GetProc(h_kernel, (char*)s_Module32First);
//##ModelId=44C4B60E0291
BOOL ApiHelp::Module32First(HANDLE hSnapshot, LPMODULEENTRY32 lpme)
{
    return fn_Module32First(hSnapshot, lpme);
}

// Module32Next
//##ModelId=44C4B60E02FE
typedef BOOL (WINAPI *PModule32Next)(HANDLE hSnapshot, LPMODULEENTRY32 lpme);
static PModule32Next fn_Module32Next = (PModule32Next)Module::GetProc(h_kernel, (char*)s_Module32Next);
//##ModelId=44C4B60E0295
BOOL ApiHelp::Module32Next(HANDLE hSnapshot, LPMODULEENTRY32 lpme)
{
    return fn_Module32Next(hSnapshot, lpme);
}

// Process32First
//##ModelId=44C4B60E030E
typedef BOOL (WINAPI *PProcess32First)(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);
static PProcess32First fn_Process32First = (PProcess32First)Module::GetProc(h_kernel, (char*)s_Process32First);
//##ModelId=44C4B60E029F
BOOL ApiHelp::Process32First(HANDLE hSnapshot, LPPROCESSENTRY32 lppe)
{
    return fn_Process32First(hSnapshot, lppe);
}

// Process32Next
//##ModelId=44C4B60E031C
typedef BOOL (WINAPI *PProcess32Next)(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);
static PProcess32Next fn_Process32Next = (PProcess32Next)Module::GetProc(h_kernel, (char*)s_Process32Next);
//##ModelId=44C4B60E02A3
BOOL ApiHelp::Process32Next(HANDLE hSnapshot, LPPROCESSENTRY32 lppe)
{
    return fn_Process32Next(hSnapshot, lppe);
}

// ReadProcessMemory
//##ModelId=44C4B60E032C
typedef BOOL (WINAPI *PReadProcessMemory)(
    IN HANDLE hProcess,
    IN LPCVOID lpBaseAddress,
    OUT LPVOID lpBuffer,
    IN SIZE_T nSize,
    OUT SIZE_T * lpNumberOfBytesRead);
static PReadProcessMemory fn_ReadProcessMemory = (PReadProcessMemory)Module::GetProc(h_kernel, (char*)s_ReadProcessMemory);
//##ModelId=44C4B60E02A7
BOOL ApiHelp::ReadProcessMemory(
    IN HANDLE hProcess,
    IN LPCVOID lpBaseAddress,
    OUT LPVOID lpBuffer,
    IN SIZE_T nSize,
    OUT SIZE_T * lpNumberOfBytesRead)
{
    return fn_ReadProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead);
}

// WriteProcessMemory
//##ModelId=44C4B60E032E
typedef BOOL (WINAPI *PWriteProcessMemory)(
    IN HANDLE hProcess,
    IN LPVOID lpBaseAddress,
    IN LPCVOID lpBuffer,
    IN SIZE_T nSize,
    OUT SIZE_T * lpNumberOfBytesWritten);
static PWriteProcessMemory fn_WriteProcessMemory = (PWriteProcessMemory)Module::GetProc(h_kernel, (char*)s_WriteProcessMemory);
//##ModelId=44C4B60E02B5
BOOL ApiHelp::WriteProcessMemory(
    IN HANDLE hProcess,
    IN LPVOID lpBaseAddress,
    IN LPCVOID lpBuffer,
    IN SIZE_T nSize,
    OUT SIZE_T * lpNumberOfBytesWritten)
{
    return fn_WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten);
}

// CreateThread
//##ModelId=44C4B60E033D
typedef HANDLE (WINAPI *PCreateThread)(
    IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
    IN SIZE_T dwStackSize,
    IN LPTHREAD_START_ROUTINE lpStartAddress,
    IN LPVOID lpParameter,
    IN DWORD dwCreationFlags,
    OUT LPDWORD lpThreadId);
static PCreateThread fn_CreateThread = (PCreateThread)Module::GetProc(h_kernel, (char*)s_CreateThread);
//##ModelId=44C4B60E02C3
HANDLE ApiHelp::CreateThread(
    IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
    IN SIZE_T dwStackSize,
    IN LPTHREAD_START_ROUTINE lpStartAddress,
    IN LPVOID lpParameter,
    IN DWORD dwCreationFlags,
    OUT LPDWORD lpThreadId)
{
    return fn_CreateThread(
        lpThreadAttributes,
        dwStackSize,
        lpStartAddress,
        lpParameter,
        dwCreationFlags,
        lpThreadId);
}

// OpenProcess
//##ModelId=44C4B60E034C
typedef HANDLE (WINAPI *POpenProcess)(
    IN DWORD dwDesiredAccess,
    IN BOOL bInheritHandle,
    IN DWORD dwProcessId);
static POpenProcess fn_OpenProcess = (POpenProcess)Module::GetProc(h_kernel, (char*)s_OpenProcess);
//##ModelId=44C4B60E02D1
HANDLE ApiHelp::OpenProcess(
    IN DWORD dwDesiredAccess,
    IN BOOL bInheritHandle,
    IN DWORD dwProcessId)
{
    return fn_OpenProcess(
        dwDesiredAccess,
        bInheritHandle,
        dwProcessId);
}

// WaitForSingleObject
//##ModelId=44C4B60E035B
typedef DWORD (WINAPI *PWaitForSingleObject)(
    IN HANDLE hHandle,
    IN DWORD dwMilliseconds);
static PWaitForSingleObject fn_WaitForSingleObject = (PWaitForSingleObject)Module::GetProc(h_kernel, (char*)s_WaitForSingleObject);
//##ModelId=44C4B60E02D6
DWORD ApiHelp::WaitForSingleObject(
    IN HANDLE hHandle,
    IN DWORD dwMilliseconds)
{
    return fn_WaitForSingleObject(hHandle, dwMilliseconds);
}

// VirtualProtectEx
//##ModelId=44C4B60E036B
typedef BOOL (WINAPI *PVirtualProtectEx)(
    IN  HANDLE hProcess,
    IN  LPVOID lpAddress,
    IN  SIZE_T dwSize,
    IN  DWORD flNewProtect,
    OUT PDWORD lpflOldProtect);
static PVirtualProtectEx fn_VirtualProtectEx = (PVirtualProtectEx)Module::GetProc(h_kernel, (char*)s_VirtualProtectEx);
//##ModelId=44C4B60E02E0
BOOL ApiHelp::VirtualProtectEx(
    IN  HANDLE hProcess,
    IN  LPVOID lpAddress,
    IN  SIZE_T dwSize,
    IN  DWORD flNewProtect,
    OUT PDWORD lpflOldProtect)
{
    return fn_VirtualProtectEx(
        hProcess,
        lpAddress,
        dwSize,
        flNewProtect,
        lpflOldProtect);
}


} // namespace JoyGuard
